import { _decorator, Component, EventKeyboard, EventTarget, Input, input, KeyCode, Label, v2, Vec2 } from 'cc';
import { bindValue } from '../platform/ui/UIDecorator';
import { UIComponent } from '../platform/ui/UIComponent';
import { MoveData } from './MoveData';
import { GameState } from './GameState';
import { NetworkManager } from './NetManager';
const { ccclass, property } = _decorator;


@ccclass('Player')
export class Player extends UIComponent {
    @bindValue(Label)
    public uid:string = ""
    @bindValue(Label)
    private pos:string = ""

    @property(Number)
    private speed:number = 100
    private currentPos: Vec2 = v2(0, 0);
    private serverPos: Vec2 = v2(0, 0);
    private velocity: Vec2 = v2(0, 0);
    private newVelocity: Vec2 = v2(0, 0);
    private moveHistory: MoveData[] = [];
    private lastMoveTime: number = 0;

    
    private _isLocal: boolean = false;
    // 用于插值的状态队列
    private stateQueue: GameState[] = [];
    private renderTimeOffset: number = 100; // 渲染延迟100ms
    
    onLoad() {
        this.schedule(this.updateInterpolation, 0.02); // 50Hz渲染更新
    }

    init(uid:string,x:number,y:number,islocal:boolean) {
        this.uid = uid;
        this._isLocal = islocal
        this.node.setPosition(x,y);
        this.pos = `${x},${y}`;
        if(this._isLocal){
                // 监听键盘事件，注意最小间隔，防止小消息太多，时间太短则不算按下
            input.on(Input.EventType.KEY_DOWN,this.onKeyDown,this)
            input.on(Input.EventType.KEY_DOWN,this.onKeyUp,this)
        }

    }

    onKeyDown(event: EventKeyboard) {

        if(event.keyCode == KeyCode.KEY_W){
            this.newVelocity.y += 1;
        }else if(event.keyCode == KeyCode.KEY_S){
            this.newVelocity.y -= 1;
        }else if(event.keyCode == KeyCode.KEY_A){
            this.newVelocity.x -= 1;
        }else if(event.keyCode == KeyCode.KEY_D){
            this.newVelocity.x += 1;
        }
        if(this.newVelocity.x==this.velocity.x && this.newVelocity.y==this.velocity.y){
            return
        }
        this.velocity.x = this.newVelocity.x;
        this.velocity.y = this.newVelocity.y;
        this.sendMoveToServer()
    }
    onKeyUp(event: EventKeyboard) {

        if(event.keyCode == KeyCode.KEY_W){
            this.newVelocity.y -= 1;
        }else if(event.keyCode == KeyCode.KEY_S){
            this.newVelocity.y += 1;
        }else if(event.keyCode == KeyCode.KEY_A){
            this.newVelocity.x += 1;
        }else if(event.keyCode == KeyCode.KEY_D){
            this.newVelocity.x -= 1;
        }
        if(this.newVelocity.x==this.velocity.x && this.newVelocity.y==this.velocity.y){
            return
        }
        this.velocity.x = this.newVelocity.x;
        this.velocity.y = this.newVelocity.y;
        this.sendMoveToServer()
    }
    protected update(dt: number): void {
        if(!this._isLocal){
            return
        }
        this.move(dt)

    }

    // 本地玩家移动预测
    public move( deltaTime: number): void {
        if(this.velocity.x==0 && this.velocity.y==0){
            return
        }

        let normalize = this.velocity.normalize()
        let moveSize = normalize.multiplyScalar(deltaTime*this.speed)
        this.node.setPosition(this.node.position.x+moveSize.x,this.node.position.y+moveSize.y) 
    }
    
    // private shouldSendMoveUpdate(): boolean {
    //     const now = Date.now();
    //     // 如果速度有变化或者超过100ms没有发送更新
    //     return this.velocity.mag() > 0 && (now - this.lastMoveTime > 100);
    // }
    
    private sendMoveToServer(): void {
        const moveData: MoveData = {
            posX: this.node.position.x,
            posY: this.node.position.y,
            velocityX: this.velocity.x,
            velocityY: this.velocity.y,
            sequence: 0,
            clientTime: 0
        };
        
        NetworkManager.getInstance().sendMove(moveData);
        // this.lastMoveTime = Date.now();
        
        // 保存移动历史用于回滚
        this.moveHistory.push({...moveData});
        if (this.moveHistory.length > 60) { // 保存最近60个移动
            this.moveHistory.shift();
        }
    }
    
    // 处理服务器状态更新
    public onServerStateUpdate(state: GameState): void {
        if (!this._isLocal) {
            // 远程玩家：添加到状态队列进行插值
            this.stateQueue.push(state);
            return;
        }
        
        // 本地玩家：服务器权威位置
        this.serverPos = v2(state.posX, state.posY);
        
        // 检查是否需要回滚
        // const distance = this.currentPos.sub(this.serverPos).mag();
        // if (distance > 10) { // 如果误差大于10像素
        //     this.reconcilePosition();
        // }
    }
    
    // 位置回滚
    private reconcilePosition(): void {
        // 回滚到服务器位置
        this.currentPos = this.serverPos.clone();
        
        // 重新应用服务器确认后的所有移动
        const networkManager = NetworkManager.getInstance();
        const serverTime = networkManager.getServerTime();
        
        // 重新模拟从服务器时间到现在的移动
        // 这里需要根据pendingMoves重新计算位置
        // 简化实现：直接使用服务器位置，然后在下一帧重新预测
        
        // this.sprite.setPosition(this.currentPos);
    }
    
    // 远程玩家插值更新
    private updateInterpolation(): void {
        if (this._isLocal || this.stateQueue.length === 0) return;
        
        const renderTime = NetworkManager.getInstance().getServerTime() - this.renderTimeOffset;
        
        // 找到渲染时间对应的两个状态
        let stateA: GameState = null;
        let stateB: GameState = null;
        
        for (let i = 0; i < this.stateQueue.length - 1; i++) {
            if (this.stateQueue[i].serverTimestamp <= renderTime && 
                this.stateQueue[i + 1].serverTimestamp >= renderTime) {
                stateA = this.stateQueue[i];
                stateB = this.stateQueue[i + 1];
                break;
            }
        }
        
        if (stateA && stateB) {
            // 计算插值比例
            const t = (renderTime - stateA.serverTimestamp) / 
                     (stateB.serverTimestamp - stateA.serverTimestamp);
            
            // 线性插值
            const interpX = stateA.posX + (stateB.posX - stateA.posX) * t;
            const interpY = stateA.posY + (stateB.posY - stateA.posY) * t;
            
            // this.sprite.setPosition(interpX, interpY);
            
            // 清理过时的状态
            this.stateQueue = this.stateQueue.filter(s => 
                s.serverTimestamp > renderTime - 500 // 保留500ms内的状态
            );
        } else if (this.stateQueue.length > 0) {
            // 使用最新的状态
            const latestState = this.stateQueue[this.stateQueue.length - 1];
            // this.sprite.setPosition(latestState.posX, latestState.posY);
        }
    }
}